home *** CD-ROM | disk | FTP | other *** search
/ TPUG - Toronto PET Users Group / TPUG Users Group CD / TPUG Users Group CD.iso / AMIGA / AMICUS / AMIBEST4.ADF / Solve / Solve.asm < prev    next >
Assembly Source File  |  1987-07-22  |  13KB  |  271 lines

  1. *
  2. *     Program to solve a linear system using FFP numbers
  3. *     Copyright ⌐ 1986 by Allen Barnett
  4. *                         Troy, NY
  5. *              
  6. *
  7. *     Declare externals so the linker can find them
  8. *
  9.             XREF     _AbsExecBase      ;base address for the exec library
  10.                                        ;jump table
  11.             XREF     _LVOOpenLibrary   ;open a library (exec)
  12.             XREF     _LVOCloseLibrary  ;close an open library (exec)
  13.  
  14.             XREF     _LVOInput         ;get an input file handle (dos)
  15.             XREF     _LVOOutput        ;get an output file handle (dos)
  16.             XREF     _LVORead          ;input from an open file (dos)
  17.             XREF     _LVOWrite         ;print to an open file (dos)
  18.  
  19.             XREF     _LVOSPDiv         ;divide d0 by d1 (math)
  20.             XREF     _LVOSPMul         ;multiply d0 by d1 (math)
  21.             XREF     _LVOSPSub         ;subtract d1 from d0 (math)
  22.  
  23.             XREF     _afp              ;convert ASCII string to FFP
  24.             XREF     _fpa              ;go the other way
  25. *
  26. *     Define macros for console I/O
  27. *
  28. WriteCon    MACRO    ;File Handle, Output String, String Length
  29.             move.l   \1,d1             ;File Handle here
  30.             move.l   \2,d2             ;String Address here
  31.             move.l   \3,d3             ;Length of the String here
  32.             jsr      _LVOWrite(a6)     ;Assumes _DOSBase in a6!!
  33.             ENDM
  34.  
  35. ReadCon     MACRO    ;File Handle, Input Buffer, Buffer Length
  36.             move.l   \1,d1             ;File Handle
  37.             move.l   \2,d2             ;Buffer Address
  38.             move.l   \3,d3             ;Buffer Length
  39.             jsr      _LVORead(a6)      ;_DOSBase had better be in a6!
  40.             ENDM
  41. *
  42. *     Open the Dos library
  43. *
  44. Solve       move.l   _AbsExecBase,a6   ;OpenLib function in exec library
  45.             move.l   #DOS_Name,a1      ;load pointer to the dos lib name
  46.             clr.l    d0                ;will accept any version
  47.             jsr      _LVOOpenLibrary(a6) ;open the library
  48.             move.l   d0,_DOSBase       ;base address returned in d0
  49.             beq      NoDOS             ;if no returned add., skip this
  50. *
  51. *     Open the Math library
  52. *
  53.             move.l   #Mathffp_Name,a1  ;load pointer to the math lib name
  54.             clr.l    d0
  55.             jsr      _LVOOpenLibrary(a6)
  56.             move.l   d0,_MathBase
  57.             beq      NoMath            ;again, if not there, can't run this
  58. *
  59. *     Get the input file handle (The console is the default device)
  60. *
  61.             move.l   _DOSBase,a6       ;Input function in dos lib
  62.             jsr      _LVOInput(a6)     ;the console input is already open
  63.                                        ;when the loader invokes a program
  64.             move.l   d0,InHand         ;save the handle from mischief
  65. *
  66. *     Get the output file handle (Console also the default output device)
  67. *
  68.             jsr      _LVOOutput(a6)    ;again, console is open upon loading
  69.             move.l   d0,OutHand        ;save this handle, too
  70. *
  71. *     Prompt the user to enter the rank of matrix
  72. *
  73.             WriteCon OutHand,#Msg1,#Msg1_Len
  74. *
  75. *     Read in the rank of the matrix
  76. *
  77.             ReadCon  InHand,#RBuf,#RBuf_Len
  78.             clr.l    d0                ;convert the input number to an int
  79.             move.b   RBuf,d0           ;get first byte of buffer
  80.             andi.b   #$0F,d0           ;strip off ASCII part
  81.             move.l   d0,Rank           ;save the result in memory
  82.             move.l   d0,d4             ;and in d4 (to be a loop counter)
  83.             subq.l   #1,d4             ;fix number of entries so DBRA works
  84.             move.l   d4,Rank_1         ;and save it
  85.             lsl.l    #2,d0             ;multiply the rank by 4: gives the
  86.             move.l   d0,RowWidth       ;number of bytes in each row, save it
  87. *
  88. *     Prompt to enter coefficients
  89. *
  90.             WriteCon OutHand,#Msg2,#Msg2_Len
  91. *
  92. *     Read each coefficient
  93. *
  94.             move.l   #Matrix,a2        ;load pointer to matrix storage
  95.             move.l   Rank_1,d4
  96. RdCoef1     move.l   Rank_1,d5         ;must read rank x rank number of coef
  97. RdCoef2     move.l   Rank,d0           ;recover rank value
  98.             move.l   #PBuf,a3          ;recover print buffer start
  99.             sub.b    d4,d0             ;calculate row value
  100.             ori.b    #'0',d0           ;convert to character
  101.             move.b   d0,(a3)+          ;put in print buffer
  102.             move.b   #',',(a3)+        ;write a comma to separate indices
  103.             move.l   Rank,d0           ;same idea
  104.             sub.b    d5,d0             ;calculate column value
  105.             ori.b    #'0',d0           ;convert to a character
  106.             move.b   d0,(a3)+          ;put in the print buffer
  107.             move.b   #':',(a3)         ;make it look neat
  108.             WriteCon OutHand,#PBuf,#4  ;print the prompt
  109.  
  110.             ReadCon  InHand,#RBuf,#RBuf_Len    ;read in the coefficient
  111.  
  112.             move.l   #RBuf,-(SP)       ;push input string add. onto stack
  113.             jsr      _afp              ;call the C function to convert the
  114.                                        ;string into an FFP
  115.             lea      4(SP),SP          ;clean up the stack
  116.             move.l   d0,(a2)+          ;save FFP into matrix
  117.  
  118.             dbra     d5,RdCoef2        ;get the next coefficient
  119.             dbra     d4,RdCoef1        ;continue until the matrix is full
  120.             move.l   a2,MatTop         ;save the end of the matrix
  121. *
  122. *     Read in the values in the solution vector
  123. *
  124.             WriteCon OutHand,#Msg3,#Msg3_Len ;print prompt for sol. vec.
  125.             move.l   #Solution,a2      ;load the pointer to the solution
  126.                                        ;vector storage area
  127.             move.l   Rank_1,d4         ;get this many values
  128. RdSol       move.l   Rank,d0           ;recover rank value
  129.             sub.b    d4,d0             ;calculate position
  130.             ori.b    #'0',d0           ;make it a character
  131.             move.b   d0,PBuf           ;copy character to print buffer
  132.             move.b   #':',PBuf+1       ;neaten the output
  133.             WriteCon OutHand,#PBuf,#2  ;print the value
  134.  
  135.             ReadCon  InHand,#RBuf,#RBuf_Len  ;read the solution value
  136.  
  137.             move.l   #RBuf,-(SP)       ;push string add. onto stack
  138.             jsr      _afp              ;call the C function
  139.             lea      4(SP),SP          ;clean up the stack
  140.             move.l   d0,(a2)+          ;save FFP in the storage area
  141.  
  142.             dbra     d4,RdSol          ;continue until all sol's read
  143.             move.l   a2,SolTop         ;save pointer to solution vec. top
  144. *
  145. *     Solve the simultaneous system
  146. *
  147.             move.l   _MathBase,a6      ;gonna do math for a while
  148.             move.l   MatTop,a2         ;recover pointer to matrix end
  149.             move.l   SolTop,a1         ;recover pointer to solution end
  150.  
  151.             move.l   Rank_1,d3         ;do for each row i
  152. BigLoop     move.l   Rank,d0           ;the next few instructions caculate
  153.             sub.b    d3,d0             ;the offset from the END of a row
  154.             lsl.l    #2,d0             ;to the diagonal element
  155.             neg.l    d0                ;=-(4*(rank - row_counter))
  156.             move.l   d0,d2             ;save this factor for later
  157.             move.l   0(a2,d0),d1       ;get the diagonal element of row i
  158.             beq      DivBy0            ;if it's zero, that's all we can do
  159.  
  160.             move.l   Rank_1,d4         ;do for each element of row i
  161.             move.l   a2,a5             ;save the row end for later
  162. Normal      move.l   -(a2),d0          ;get the next element
  163.             jsr      _LVOSPDiv(a6)     ;divide by the diag. (in d1)
  164.             move.l   d0,(a2)           ;store it back in the array
  165.             dbra     d4,Normal         ;continue until row i normalized
  166.                                        ;Note: a2 left pointing to END of the
  167.                                        ;row i-1
  168.             move.l   -(a1),d0          ;get solution vector element
  169.                                        ;corresponding to row i
  170.             jsr      _LVOSPDiv(a6)     ;divided by same diag element (d1)
  171.             move.l   d0,(a1)           ;save it back in the vector
  172.  
  173.             move.l   SolTop,a0         ;the operations below will leave
  174.                                        ;the problem solution in the sol vec
  175.             move.l   MatTop,a4         ;zero the elements in each row (j)
  176.             move.l   Rank_1,d4         ;above and below the diag. of row i
  177. ElimCol     cmp.l    d4,d3             ;skip this if j=i
  178.             beq      NextRow
  179.             move.l   a5,a3             ;recover the pointer to the end of
  180.                                        ;row i
  181.             move.l   0(a4,d2),d6       ;get the diag. ele. of row j
  182.             move.l   Rank_1,d5         ;do for each element of row j
  183. FixRow      move.l   -(a3),d0          ;get the element of row i to be
  184.             move.l   d6,d1             ;multiplied by the diag. ele. of j
  185.             jsr      _LVOSPMul(a6)     ;multiply them
  186.             move.l   d0,d1             ;switch around the result
  187.             move.l   -(a4),d0          ;get the affected element of row j
  188.             jsr      _LVOSPSub(a6)     ;subtract our product
  189.             move.l   d0,(a4)           ;save the result back in the matrix
  190.             dbra     d5,FixRow         ;continue for each element of row j
  191.             move.l   d6,d1             ;also, do the same mult. and sub.
  192.             move.l   (a1),d0           ;on the solution vector ele.
  193.             jsr      _LVOSPMul(a6)
  194.             move.l   d0,d1
  195.             move.l   -(a0),d0
  196.             jsr      _LVOSPSub(a6)
  197.             move.l   d0,(a0)
  198.             bra      ReLoop            ;skip the rest
  199. NextRow     suba.l   RowWidth,a4       ;if j=i then advance the row j
  200.             subq.l   #4,a0             ;pointers to the next row, j-1
  201. ReLoop      dbra     d4,ElimCol
  202.             dbra     d3,BigLoop        ;That's all for now
  203. *
  204. *     All done so print the answers
  205. *
  206.             move.l   _DOSBase,a6       ;back to writing
  207.             WriteCon OutHand,#Msg5,#Msg5_Len ;print a line to this effect
  208.             move.l   #Solution,a2      ;get the start of the sol. vec.
  209.             move.l   Rank_1,d5         ;print the correct number of entries
  210. SolLp2      move.l   #PBuf,-(SP)       ;push the buffer address
  211.             move.l   d0,-(SP)          ;WARNING: this does nothing, but is
  212.                                        ;essential for the operation of _fpa
  213.             move.l   (a2)+,-(SP)       ;push the FFP to convert to a string
  214.             jsr      _fpa              ;call the routine to convert it
  215.             lea      12(SP),SP         ;clean up the stack
  216.             move.w   lf,PBuf+14        ;add a line feed to the buffer
  217.             WriteCon OutHand,#PBuf,#16 ;print it out
  218.             dbra     d5,SolLp2         ;continue until all printed
  219.             bra      CloseShop         ;go to the end
  220.  
  221. DivBy0      move.l   _DOSBase,a6       ;Uh Oh! Gotta stop
  222.             WriteCon OutHand,#Msg4,#Msg4_Len ;print the bad news
  223.  
  224. CloseShop   move.l   _AbsExecBase,a6   ;CloseLib in exec library
  225.             move.l   _MathBase,a1      ;close the Math library
  226.             jsr      _LVOCloseLibrary(a6) ;close it
  227.  
  228. NoMath      move.l   _AbsExecBase,a6
  229.             move.l   _DOSBase,a1       ;close the dos library
  230.             jsr      _LVOCloseLibrary(a6)
  231.  
  232. NoDOS       clr.l    d0                ;things went pretty well, bye.
  233.             rts
  234.  
  235.             SECTION  data,DATA
  236. DOS_Name    dc.b     'dos.library',0
  237. Mathffp_Name:
  238.             dc.b     'mathffp.library',0
  239. Msg1        dc.b     'Enter the rank of the coefficient matrix',13,10
  240. Msg1_Len    EQU      *-Msg1
  241. Msg2        dc.b     'Enter the coefficients as requested (row,col)',13,10
  242. Msg2_Len    EQU      *-Msg2
  243. Msg3        dc.b     'Enter the solution vector (row)',13,10
  244. Msg3_Len    EQU      *-Msg3
  245. Msg4        dc.b     'Oops.  Division by zero!',13,10
  246. Msg4_Len    EQU      *-Msg4
  247. Msg5        dc.b     'The unknowns are:',13,10
  248. Msg5_Len    EQU      *-Msg5
  249. lf          dc.w     $0D0A
  250.  
  251.             SECTION  mem,BSS
  252. * variables
  253. _DOSBase    ds.l     1
  254. _MathBase   ds.l     1
  255. InHand      ds.l     1
  256. OutHand     ds.l     1
  257. Rank        ds.l     1
  258. Rank_1      ds.l     1
  259. RowWidth    ds.l     1
  260. MatTop      ds.l     1
  261. SolTop      ds.l     1
  262. * buffers
  263. RBuf        ds.b     80
  264. RBuf_Len    EQU      *-RBuf
  265. PBuf        ds.b     80
  266. PBuf_Len    EQU      *-PBuf
  267. Matrix      ds.l     81
  268. Solution    ds.l     9
  269.             END
  270.  
  271.